package com.hardydou.jmm;

import java.util.concurrent.Callable;

/**
 * 可见性 示例
 * <p>
 * isRunning 去掉 volatile 就会有延迟或者无法同步
 * <p>
 * 测试发现，
 * <p>
 * 1、只有有通过主存拉去数据的可能就一定会获取到最新数据
 * 2、通过申请空间 强制刷新 trhead缓存 可以从主存拉去数据。
 * 3、构建语句 获取 runover值的下一条语句还是 获取runover值 就不会有更新缓存的机会。
 *
 * @author hardy
 */
public class Visibility implements Callable<Visibility> {

    static volatile boolean runOverOfVolatile;
    static boolean runOver;
    boolean isMonitor;
    boolean useVolatile;

    public Visibility(boolean isMonitor, boolean useVolatile) {
        this.isMonitor = isMonitor;
        this.useVolatile = useVolatile;
    }

    public Visibility call() {
        if (isMonitor) {
            getResult();
            return this;
        } else {
            work();
            return this;
        }

    }

    public void work() {
        try {
            Thread.sleep(500L);
        } catch (Exception e) {
        }
        if (useVolatile) {
            runOverOfVolatile = true;
        } else {
            runOver = true;
        }
        System.out.println("Visibility.work");
    }

    public boolean getResult() {
        while (true) {
            //do somethings
            // 刷新线程本地缓存就会同步值
            //byte[] ss = new byte[102400];
            if (useVolatile) {
                if (runOverOfVolatile) {
                    break;
                }
            } else {
                if (runOver) {
                    break;
                }
            }
        }
        System.out.println("Visibility.getResult");
        return true;
    }

}

